﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace GurLoader.View
{
    public class HotKeyTextBox : TextBox
    {
        public static readonly DependencyProperty ShortcutKeyProperty = DependencyProperty.Register(
            "ShortcutKey", typeof (Key), typeof (HotKeyTextBox),
            new FrameworkPropertyMetadata(
                Key.None,
                FrameworkPropertyMetadataOptions.AffectsRender,
                OnShortcutKeyPropertyChanged));

        public static readonly DependencyProperty ShortcutModifierKeysProperty = DependencyProperty.Register(
            "ShortcutModifierKeys", typeof (ModifierKeys), typeof (HotKeyTextBox),
            new FrameworkPropertyMetadata(
                ModifierKeys.None,
                FrameworkPropertyMetadataOptions.AffectsRender,
                OnShortcutModifierKeyPropertyChanged));

        private IKeyboard CurrentKeyboard { get; set; }


        static HotKeyTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(HotKeyTextBox), new FrameworkPropertyMetadata(typeof(HotKeyTextBox)));
        }

        public HotKeyTextBox() : this( new DefaultKeyboardWrapper() )
        {
        }

        public HotKeyTextBox(IKeyboard kbd)
        {
            CurrentKeyboard = kbd;
        }

        protected static void OnShortcutKeyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var hktb = (HotKeyTextBox) d;
            hktb.ShortcutKey = (Key) e.NewValue;
        }

        protected static void OnShortcutModifierKeyPropertyChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            var hktb = (HotKeyTextBox) d;
            hktb.ShortcutModifierKeys = (ModifierKeys) e.NewValue;
        }

        public Key ShortcutKey
        {
            get { return (Key) GetValue(ShortcutKeyProperty); }
            set
            {
                SetValue(ShortcutKeyProperty, value); 
                SetShortcutText();
            }
        }

        public ModifierKeys ShortcutModifierKeys
        {
            get { return (ModifierKeys) GetValue(ShortcutModifierKeysProperty); }
            set
            {
                SetValue(ShortcutModifierKeysProperty, value); 
                SetShortcutText();
            } 
        }

        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            e.Handled = true;

            Key key = (e.Key == Key.System ? e.SystemKey : e.Key);
            ModifierKeys modifierKeys = CurrentKeyboard.Modifiers;

            ShortcutKey = key;
            ShortcutModifierKeys = modifierKeys;

            base.OnPreviewKeyDown(e);
        }

        private void SetShortcutText()
        {
            string shortcutText = BuildShortcutText(ShortcutKey, ShortcutModifierKeys);
            if (! string.IsNullOrEmpty(shortcutText))
                Text = shortcutText;
        }

        private string BuildShortcutText(Key key, ModifierKeys modifierKeys)
        {
            if (key == Key.LeftShift || key == Key.RightShift
                || key == Key.LeftCtrl || key == Key.RightCtrl
                || key == Key.LeftAlt || key == Key.RightAlt
                || key == Key.LWin || key == Key.RWin)
            {
                return string.Empty;
            }

            StringBuilder shortcutText = new StringBuilder();
            if ((modifierKeys & ModifierKeys.Control) != 0)
            {
                shortcutText.Append("Ctrl+");
            }
            if ((modifierKeys & ModifierKeys.Shift) != 0)
            {
                shortcutText.Append("Shift+");
            }
            if ((modifierKeys & ModifierKeys.Alt) != 0)
            {
                shortcutText.Append("Alt+");
            }
            shortcutText.Append(key.ToString());

            return shortcutText.ToString();
        }
    }
}
